#include "BestQuoteProcess.h"
#include "BestQuoteData.h"
#include "core/comdefs.h"
#include <core/QbLogger.h>
#include <qbprotocol/include/SSQBAModel.h>
#include <chrono>
#include <QTimer>

#ifndef max
#define max(a,b)            ((a) > (b)) ? (a) : (b)
#endif

BestQuoteProcess::BestQuoteProcess(std::map<std::string, int>* indexMap)
    : m_pIndexMap(indexMap)
{
    moveToThread(this);
    connect(this, &BestQuoteProcess::workerProcessData, this, &BestQuoteProcess::onWorkerProcessData);
}

BestQuoteProcess::~BestQuoteProcess()
{
    quit();
    wait();
}

void BestQuoteProcess::start()
{
    QThread::start();
}

void BestQuoteProcess::run()
{
    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(OnTimer()), Qt::UniqueConnection);
    timer->setInterval(50);
    timer->start();

    exec();

    timer->stop();
    timer = NULL;
}

void BestQuoteProcess::OnTimer()
{
    QB_CHECK_RETURN_VOID1(m_pIndexMap);

	const int  minReportCount = 64;
    const int  maxReportCount = 512;
    static BondIndexBroker* pbk = NULL;
    static REPORT2* prpt = NULL;
    static uint32_t datacount = 0;

    while (m_lstData.size() > 0)
	{
		if (!pbk) pbk = new BondIndexBroker[maxReportCount];
		if (!prpt) prpt = new REPORT2[maxReportCount];

        xQBBestPriceListAck_c* pData = (xQBBestPriceListAck_c*)m_lstData.front();
        if (!pData)
		{
			m_lstData.pop_front();
            continue;
        }

        m_lstData.pop_front();

        if (pData->m_List.size() <= 0)break;

        for (std::list<xQBBestPriceUnit_c>::iterator it = pData->m_List.begin(); it != pData->m_List.end(); ++it)
        {
            xQBBestPriceUnit_c& unit = *it;
            int brokerId = atoi(unit.m_company_id);
            std::string sKey = unit.m_bondkey;
            sKey.append("_");
            sKey.append(unit.m_listedmarket);
            auto iid = m_pIndexMap->find(sKey);
            if (iid == m_pIndexMap->end())
            {
                log_debug("%s bondKey[%s] not found", __FUNCTION__, sKey.c_str());
                continue;
            }

            uint32_t bondIndex = iid->second;
         //   if (bondIndex < 0 || bondIndex >= m_pBondList->size())
            {
                log_debug("&s bondIndex[%d] is out of vector size", __FUNCTION__, bondIndex);
                continue;
            }

            pbk[datacount].bondIndex = bondIndex;
            pbk[datacount].brokerId = brokerId;

            strcpy(prpt[datacount].m_sBondKey, unit.m_bondkey);
            strcpy(prpt[datacount].m_sListedMarket, unit.m_listedmarket);
            strcpy(prpt[datacount].m_company_id, unit.m_company_id);
            prpt[datacount].m_dwVersion = unit.m_version;
            prpt[datacount].m_time = max(unit.m_modify_time, unit.m_create_time);
            prpt[datacount].m_dir = atoi(unit.m_symbol);

            if (prpt[datacount].m_dir == 1)
            {
                prpt[datacount].m_bidinfo.SetPrice(unit);
            }
            else
            {
                prpt[datacount].m_askinfo.SetPrice(unit);
            }

            datacount++;

            if (datacount >= maxReportCount)
            {
                BestQuoteProcessData* pd = new BestQuoteProcessData;
                pd->pbib = pbk;
                pd->prpt = prpt;
                pd->count = datacount;
                emit processFinish(pd);

                pbk = new BondIndexBroker[maxReportCount];
                prpt = new REPORT2[maxReportCount];
                datacount = 0;
            }
        }
        
        emit freeAckData(pData);
        if (datacount >= minReportCount)break;
    }

    if (datacount > 0)
    {
        BestQuoteProcessData* pd = new BestQuoteProcessData;
        pd->pbib = pbk;
        pd->prpt = prpt;
        pd->count = datacount;

        emit processFinish(pd);

        pbk = NULL;
        prpt = NULL;
        datacount = 0;
    }
}

void BestQuoteProcess::processData(void* data)
{
    emit workerProcessData(data);
}

void BestQuoteProcess::onWorkerProcessData(void* data)
{
    m_lstData.push_back(data);
}
